home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech's Sprocket™ / SprocketGX / Lib / DialogWindow.cp < prev    next >
Encoding:
Text File  |  1994-10-17  |  4.9 KB  |  194 lines  |  [TEXT/MMCC]

  1. /*
  2.     File:        DialogWindow.cp
  3.  
  4.     Contains:    Implementation of a base class for Modeless Dialogs
  5.                 
  6.     Written by: Dave Falkenburg
  7.  
  8.     Copyright:    © 1993-94 by Dave Falkenburg, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.     To Do:
  13.  */
  14.  
  15. #include    <Dialogs.h>
  16. #include    <Menus.h>
  17. #include    <Desk.h>
  18. #include    <Traps.h>
  19. #include    <Devices.h>
  20.  
  21. #include    "DialogWindow.h"
  22. #include    "AppLib.h"
  23.  
  24.  
  25. TDialogWindow::TDialogWindow(DialogTemplateID dialogTemplateID)
  26.  : fTemplateID(dialogTemplateID)
  27. {
  28.     this->CreateWindow(kNormalWindow);
  29. }
  30.  
  31.  
  32. WindowPtr TDialogWindow::MakeNewWindow(WindowPtr behindWindow)
  33. {
  34.     return GetNewDialog(fTemplateID,nil,behindWindow);
  35. }
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////////
  38. //
  39. //    EventFilter strategy for Dialog Window
  40. //
  41. //    Because of the need to patch and unpatch FrontWindow when calling IsDialogEvent
  42. //    and DialogSelect, only do these things when a Modless Dialog is the frontmost
  43. //    window. (e.g., it’s event filter is active)
  44. //
  45. //    NOTE: We always pass events through, except when an item has been hit.
  46. //
  47. //    You may be thinking that it is easier to just rewrite the Dialog Manager in
  48. //    this program. You’re probably right.
  49.  
  50. pascal    WindowPtr    FrontWindowPatchForDialogs();
  51.  
  52. pascal    WindowPtr
  53. FrontWindowPatchForDialogs()
  54. {
  55.     return FrontNonFloatingWindow();
  56. }
  57.  
  58. #define    uppFrontWindowPatchProcInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
  59.  
  60. UniversalProcPtr FrontWindowPatchUPP
  61. = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) &FrontWindowPatchForDialogs,uppFrontWindowPatchProcInfo,GetCurrentISA());
  62.  
  63.  
  64. Boolean TDialogWindow::EventFilter(EventRecord *theEvent)
  65. {
  66.     UniversalProcPtr    oldFrontWindow = GetToolboxTrapAddress(_FrontWindow);
  67.     DialogPtr            aDialog;
  68.     Boolean                eventHasBeenGobbled = false;
  69.     short                aDialogItem;
  70.     short                oldWindowKind;
  71.     
  72.     //    Don’t snarf keypresses meant for menus
  73.     if ((theEvent->what == keyDown) && (theEvent->modifiers & cmdKey))
  74.         return false;
  75.         
  76.     //    Patch in our version of FrontWindow so that IsDialogEvent will do the right
  77.     //    thing. DialogManager should check both frontmost floating and frontmost
  78.     //    non-floating windows, however we don’t support floating dialogs.
  79.     SetToolboxTrapAddress(FrontWindowPatchUPP,_FrontWindow);
  80.  
  81.     //    Jam the windowKind of our dialog window back to dialogKind so that the
  82.     //    Dialog Manager can recognize our window as a dialog window.
  83.     oldWindowKind = ((WindowPeek) fWindow)->windowKind;
  84.     ((WindowPeek) fWindow)->windowKind = dialogKind;
  85.     
  86.     if (IsDialogEvent(theEvent))
  87.         if (DialogSelect(theEvent,&aDialog,&aDialogItem))
  88.             eventHasBeenGobbled = true;
  89.  
  90.     //    Restore the windowKind
  91.     ((WindowPeek) fWindow)->windowKind = oldWindowKind;
  92.  
  93.     //    Put FrontWindow back the way it really belongs
  94.     SetToolboxTrapAddress((UniversalProcPtr) oldFrontWindow,_FrontWindow);
  95.  
  96.     if (eventHasBeenGobbled)
  97.     {
  98.         ItemHit(aDialogItem);    //    Call user’s method to deal with a hit
  99.         return true;
  100.     }
  101.  
  102.     return(false);
  103. }
  104.  
  105. void TDialogWindow::Activate(Boolean activating)
  106. {
  107.     /*    (De)activates are NOT automagically handled because our floating
  108.      *    windows prevent real activate events from ever being generated
  109.      *    for any non-floaters windows.
  110.      *
  111.      *    Our strategy is to fool the dialog manager into thinking that
  112.      *    things are still fine by passing it a fake (de)activate event.
  113.      *
  114.      *    Luckily, we don’t have to patch FrontWindow to make DialogSelect
  115.      *    work for activate and update events.
  116.      */
  117.     
  118.     EventRecord            fakeEvent;
  119.         
  120.     OSEventAvail(0,&fakeEvent);        //    Get an intialized, but otherwise empty event record
  121.     
  122.     fakeEvent.what = activateEvt;
  123.     fakeEvent.message = (unsigned long) fWindow;
  124.     if (activating)
  125.         fakeEvent.modifiers |= activeFlag;
  126.     else
  127.         fakeEvent.modifiers &= ~activeFlag;
  128.  
  129.     //    Pass event on to DialogSelect
  130.     
  131.     DialogPtr    aDialog;
  132.     short        aDialogItem;
  133.     
  134.     (void) DialogSelect(&fakeEvent,&aDialog,&aDialogItem);
  135. }
  136.     
  137.  
  138. void
  139. TDialogWindow::Draw(void)
  140. {
  141.     //    Automagically handled by Dialog Manager when we are
  142.     //    the frontmost window, but not at other times because
  143.     //    we only set the windowKind to dialogKind inside our
  144.     //    EventFilter (which is only active when we are frontmost).
  145.     
  146.     UpdateDialog((DialogPtr) fWindow, fWindow->visRgn);
  147. }
  148.     
  149. void TDialogWindow::Click(EventRecord * /* pEvent */)
  150. {
  151.     /*    The only time this method is called is to handle a click
  152.      *    when the dialog window isn’t frontmost. All other times,
  153.      *    DialogSelect will do everything for us.
  154.      *
  155.      *    If our dialog contains useritems with the ability to
  156.      *    be the source of a drag we’d need to start drag tracking
  157.      *    in here.
  158.      */
  159.      
  160.     this->Select();
  161. }
  162.  
  163.     
  164. void TDialogWindow::DoEditMenu(short item)
  165. {
  166.     switch (item+accMenu)
  167.     {
  168.         case    accUndo:
  169.             break;
  170.             
  171.         case    accCut:
  172.             DlgCut((DialogPtr) &fWindow); 
  173.             break;
  174.             
  175.         case    accCopy:
  176.             DlgCopy((DialogPtr) &fWindow); 
  177.             break;
  178.             
  179.         case    accPaste:
  180.             DlgPaste((DialogPtr) &fWindow); 
  181.             break;
  182.             
  183.         case    accClear:
  184.             DlgDelete((DialogPtr) &fWindow); 
  185.             break;
  186.     }
  187. }
  188.  
  189. void
  190. TDialogWindow::ItemHit(short /* theItem */)
  191. {
  192.     /*    Override this function to handle dialog items */
  193. }
  194.